package com.lcz.licence.util;

import com.lcz.licence.entity.LicenseCreatorParam;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import sun.security.x509.X500Name;

import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;


/**
 * @author lcz
 * @desc 密钥存储生成器
 * @mail lcz_0130@163.com
 * @date 2025/07/21
 */

public class KeyStoreGenerator {

    private LicenseCreatorParam param;

    public KeyStoreGenerator(LicenseCreatorParam param) {
        this.param = param;
    }

    /**
     * 生成密钥和导出导入证书
     */
    public void generateAndImportKeys() throws Exception {
        // 生成私钥库
        KeyStore privateKeyStore = generateKeyStore();
        String privateKeysStorePath = param.getPrivateKeysStorePath();
        //判断文件是否存在，存在则删除
        File keyStoreFile = new File(privateKeysStorePath);
        if (keyStoreFile.exists()) {
            keyStoreFile.delete();
        }
        // 保存私钥库到文件
        try (FileOutputStream fos = new FileOutputStream(privateKeysStorePath)) {
            privateKeyStore.store(fos, param.getStorePass().toCharArray());
        }
        // 从私钥库导出证书
        String certPath = exportCertificate(privateKeyStore);
        // 导入证书到公钥库
        importPublicCertificate(certPath);
    }


    /**
     * 生成密钥存储
     */
    public KeyStore generateKeyStore() throws Exception {
        String alias = param.getPrivateAlias();
        String storePass = param.getStorePass();
        String keyPass = param.getKeyPass();

        Date startDate = param.getIssuedTime();
        Date endDate = param.getExpireTime();

        // 添加BouncyCastle安全提供者
        Security.addProvider(new BouncyCastleProvider());

        // 生成DSA密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "BC");
        keyGen.initialize(1024, new SecureRandom());
        KeyPair keyPair = keyGen.generateKeyPair();

        // 创建X.500发行者/主题名称（固定DN）
        X500Principal defaultHolderAndIssuer = LicenseCreator.DEFAULT_HOLDER_AND_ISSUER;
        X500Name issuer = new X500Name(defaultHolderAndIssuer.getName());

        // 构建X.509证书
        X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
                issuer.asX500Principal(),
                BigInteger.valueOf(System.currentTimeMillis()),
                startDate,
                endDate,
                issuer.asX500Principal(),
                keyPair.getPublic()
        );

        // 使用私钥签名证书
        ContentSigner signer = new JcaContentSignerBuilder("SHA256WithDSA").build(keyPair.getPrivate());
        X509Certificate cert = new JcaX509CertificateConverter()
                .setProvider("BC")
                .getCertificate(certBuilder.build(signer));

        // 创建KeyStore并保存
        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(null, storePass.toCharArray());
        keyStore.setKeyEntry(
                alias,
                keyPair.getPrivate(),
                keyPass.toCharArray(),
                new java.security.cert.Certificate[]{cert}
        );
        return keyStore;
    }


    // 导出证书到临时文件
    private String exportCertificate(KeyStore privateKeyStore) throws Exception {
        String alias = param.getPrivateAlias();
        // 从私钥库获取证书
        java.security.cert.Certificate cert = privateKeyStore.getCertificate(alias);
        // 创建临时证书文件
        String certPath = File.createTempFile("cert-", ".cer").getAbsolutePath();
        // 将证书写入文件
        try (FileOutputStream fos = new FileOutputStream(certPath)) {
            fos.write(cert.getEncoded());
        }

        return certPath;
    }

    // 导入证书到公钥库
    private void importPublicCertificate(String certPath) throws Exception {
        String publicAlias = param.getPublicAlias();
        String storePass = param.getStorePass();

        // 从参数获取公钥库路径，如果没有则使用默认路径
        String publicStorePath = param.getPublicKeysStorePath();

        //判断文件是否存在，存在则删除
        File keyStoreFile = new File(publicStorePath);
        if (keyStoreFile.exists()) {
            keyStoreFile.delete();
        }

        // 加载或创建公钥库
        KeyStore publicKeyStore;
        File publicKeyFile = new File(publicStorePath);

        if (publicKeyFile.exists()) {
            // 加载现有公钥库
            publicKeyStore = KeyStore.getInstance("JKS");
            try (FileInputStream fis = new FileInputStream(publicKeyFile)) {
                publicKeyStore.load(fis, storePass.toCharArray());
            }
        } else {
            // 创建新公钥库
            publicKeyStore = KeyStore.getInstance("JKS");
            publicKeyStore.load(null, storePass.toCharArray());
        }

        // 读取证书文件
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        try (FileInputStream fis = new FileInputStream(certPath)) {
            java.security.cert.Certificate cert = cf.generateCertificate(fis);

            // 导入证书到公钥库
            publicKeyStore.setCertificateEntry(publicAlias, cert);

//            File keyStoreFile = new File(publicStorePath);
//            if (keyStoreFile.exists()) {
//                keyStoreFile.delete();
//            }

            // 保存公钥库
            try (FileOutputStream fos = new FileOutputStream(publicStorePath)) {
                publicKeyStore.store(fos, storePass.toCharArray());
            }
        }

        // 删除临时证书文件
        new File(certPath).delete();
    }


}

